package com.hailiao.devicebasicsdkdemo.fragment

import android.Manifest
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.clj.fastble.BleManager
import com.clj.fastble.data.BleDevice
import com.dlong.dialog.JustLoadDialog
import com.eazypermissions.common.model.PermissionResult
import com.eazypermissions.coroutinespermission.PermissionManager
import com.hailiao.devicebasicsdkdemo.R
import com.hailiao.devicebasicsdkdemo.adapter.DeviceBleAdapter
import com.hailiao.devicebasicsdkdemo.databinding.FragmentScanBinding
import com.hailiao.devicebasicsdkdemo.utils.fixSwipeRefreshClash
import com.hailiao.devicebasicsdkdemo.utils.isLocationServerEnabled
import com.hailiao.devicebasicsdkdemo.utils.showToast
import com.hailiao.hlblelib.HLBleManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 设备扫描页面
 *
 * @Author: D10NG
 * @Time: 2020/12/16 7:32 下午
 */
class ScanFragment : BaseFragment() {

    private lateinit var binding: FragmentScanBinding
    private lateinit var adapter: DeviceBleAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_scan, container, false)
        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        // 监听扫描设备变化
        HLBleManager.instance(act.application).scanDeviceListLive.observe(this.viewLifecycleOwner, { list ->
            // 更新列表显示，根据名字是否为空来筛选
            adapter.update(list?.filter { !it.name.isNullOrEmpty() }?: listOf())
        })

        // 刷新
        binding.srLayout.setOnRefreshListener {
            scanDevice()
        }

        // 初始化列表
        adapter = DeviceBleAdapter()
        binding.rcv.layoutManager = LinearLayoutManager(act)
        binding.rcv.adapter = adapter
        // 避免滑动冲突
        binding.rcv.fixSwipeRefreshClash(binding.srLayout)

        // 列表点击
        adapter.setListener {
            onClick { _, _, data ->
                val bleDevice = data as BleDevice
                val bleManager = HLBleManager.instance(act.application)
                val dialog = JustLoadDialog(act).create().show()
                GlobalScope.launch {
                    // 连接设备
                    if (!bleManager.connectDevice(bleDevice)){
                        withContext(Dispatchers.Main) {
                            act.showSnackBar("连接失败")
                            dialog.dismiss()
                        }
                        return@launch
                    }
                    // 打开通知
                    if (!bleManager.startNotify(bleDevice)) {
                        withContext(Dispatchers.Main) {
                            act.showSnackBar("打开通知失败！")
                            dialog.dismiss()
                        }
                        return@launch
                    }
                    // 完全连接成功
                    withContext(Dispatchers.Main) {
                        act.connectedBleDeviceLive.postValue(bleDevice)
                        act.showToast("连接成功！")
                        dialog.dismiss()
                        // 跳转控制页面
                        navController.navigate(R.id.action_scanFragment_to_sendFragment)
                    }
                }
            }
        }
    }

    /**
     * 扫描设备
     */
    private fun scanDevice() {
        val bleManager = HLBleManager.instance(act.application)
        // 检查蓝牙开关状态
        if (!BleManager.getInstance().isBlueEnable) {
            BleManager.getInstance().enableBluetooth()
            binding.srLayout.isRefreshing = false
            act.showSnackBar("蓝牙未打开！")
            return
        }
        // 检查定位权限
        GlobalScope.launch {
            if (!requestLocationPermission()) {
                withContext(Dispatchers.Main) {
                    binding.srLayout.isRefreshing = false
                    act.showSnackBar("获取定位权限失败！")
                }
                return@launch
            }
            // 检查位置信息开关
            if (!act.isLocationServerEnabled()) {
                withContext(Dispatchers.Main) {
                    binding.srLayout.isRefreshing = false
                    act.showSnackBar("位置信息已关闭，无法进行蓝牙扫描！")
                }
                return@launch
            }
            // 开始扫描
            withContext(Dispatchers.Main) {
                binding.srLayout.isRefreshing = true
            }
            bleManager.scanDevice()
            // 扫描结束
            withContext(Dispatchers.Main) {
                binding.srLayout.isRefreshing = false
            }
        }
    }

    /** 请求定位权限 */
    private suspend fun requestLocationPermission(): Boolean {
        try {
            val permissionResult = PermissionManager.requestPermissions(
                    this,
                    P_ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION
            )
            return when (permissionResult) {
                is PermissionResult.PermissionGranted -> {
                    // 获取权限成功
                    true
                }
                else -> {
                    // 拒绝权限
                    false
                }
            }
        } catch (e: Exception) {
            return false
        }
    }
}

/**
 * 权限请求码
 */
private const val P_ACCESS_FINE_LOCATION = 100